<?php

namespace App\Http\Controllers\Home;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Model\Home\Mongodb;

class MongoController extends Controller
{
    //操作php7以下的mongodb demo积累。
    public function testMongo(){
        $collection=$this->mongoConnect();
        $doc=[
            'First_name'=>'jet',
            'Last_name'=>'wu',
            'Age'=>31,
            'Phone'=>'111',
            'Phone'=>'111',
            'lang'=>'china',
            'Address'=>[
                'Country'=>'China',
                'City'=>'Shen Zhen'
            ],
            'E-Mail'=>[
                '123456@qq.com',
                '666666@qq.com',
                '777777@qq.com'
            ]
        ];

        $res=$collection->insert($doc);
        //$res = $collection->update(['Last_name' => 'wu'], ['$setOnInsert' => ['lang' => 'English']], ['upsert' => true]);

        print_r($res);
    }
    //查询mongo数据模型数据。
    public function queryMongoData(){
        $collection=$this->mongoConnect();
        $one=$collection->findOne(['First_name'=>'jet']);
        print_r($one);
    }
    //获取子元素列表
    public function  querySubList(){
        $collection=$this->mongoConnect();
        $cursor=$collection->find(['Address.Country'=>'China']);
        //取出的是具体的不同值数组。
        $info=$collection->distinct("Phone");


//        dd($cursor);
//        die;
        while($doc=$cursor->getNext()){
           // print_r($doc);
            echo "<pre>";
            var_dump($doc);
            echo "</pre>";
        }
    }
    //查询自定义文档
    public function selfDefinedQuery(){
        //查询字段在某个范围。
        $collection=$this->mongoConnect();
        $areaArray=array('China','USA');
        //查询地区是否属于某个数组
       // $cursor=$collection->find(['Address.Country'=>['$in'=>$areaArray]]);
        //查找年龄小于30的记录
        //$cursor=$collection->find(['Age'=>['$lt'=>30]]);
        //匹配多个值中的所有值，数组有多个的时候。
      //  $cursor=$collection->find(['E-Mail'=>['$all'=>['123456@qq.com','777777@qq.com']]]);
        //or查询的匹配
        // $cursor=$collection->find(['$or'=>[['Phone'=>'111'],['E-Mail'=>['$all'=>['123456@qq.com','777777@qq.com']]]]]);
         //and的使用
      //  $cursor=$collection->find(['$and'=>[['Phone'=>'111'],['E-Mail'=>['$all'=>['123456@qq.com','777777@qq.com']]]]]);
        //数据查询控制子元素的个数
//        $cursor = $collection->find(['First Name' => 'Jet'], ['E-Mail' => ['$slice' => 2]]);//只返回前两个email
//        $cursor = $collection->find(['First Name' => 'Jet'], ['E-Mail' => ['$slice' => -2]]);//只返回最后两个email
//        $cursor = $collection->find(['First Name' => 'Jet'], ['E-Mail' => ['$slice' => [1, 2]]]);//忽略第一个，返回接下来两个
           //$exists:根据某个字段是否有设置值进行查询,进行mongo数据模型异构的重要判断条件
        //$cursor=$collection->find(['Hobby'=>['$exists'=>false]]);
        //正则表达式查询
        $cursor=$collection->find(['First_name'=>new \MongoRegex('/^je/i')]);
        //进行数据的排序1升序，-1降序
        $cursor->sort(['Age'=>-1]);
        //分页功能
        //当前条数
        $cursor->skip(1);
        //每页多少条
        $cursor->limit(5);
        //指定索引查询,索引不存在报错,方法已经失效
        //$cursor=$collection->hint(['Last_name'=>-1]);
        while($doc=$cursor->getNext()){
            de($doc);
        }
    }
    //聚合函数计算案例
    public function polymerization(){
        $collection=$this->mongoConnect();
        //版本兼容问题，现在会报错。
        /*$res = $collection->aggregate([
            '$group' => [
                '_id' => '$Address.Country',//分组字段，注意要加上“$”，这里是根据数组字段某个元素值进行分组
                'total' => ['$sum' => 1],//求总和，表示每匹配一个文档总和就加1
                'maxAge' => ['$max' => '$Age'],//分组中Age字段最大值
                'minAge' => ['$min' => '$Age']//分组中Age字段最小值
            ]
        ]);
        de($res);*/
        $cursor=$collection->find(['Address.Country'=>'China']);
        $res = $collection->aggregate([
            [//过滤条件：只对符合条件的原始文档进行聚合运算，若是放在'$group'之后则是只返回符合条件的结果文档
                '$match' => ['Age' => ['$gt' => 30]]
            ],
            [//指定分组字段、统计字段
                '$group' => [
                    '_id' => '$Address.Country',
                    'totalAge' => ['$sum' => '$Age']//计算各个分组Age字段总和
                ]
            ],
            //以下操作若是放在'$group'之前则在聚合前作用于原始文档，若放在'$group'之后则在聚合后作用于结果文档
            ['$unwind' => '$E-Mail'],//将包含有某个数组类型字段的文档拆分成多个文档，每个文档的同名字段的值为数组中的一个值。
            ['$project' => ['myAge' => '$Age', 'First Name' => '$First Name']],//指定返回字段，可以对字段进行重命名，格式：返回字段名 => $原来字段名
            ['$skip' => 2],//跳过指定数量的文档
            ['$limit' => 2],//只返回指定数量的文档
            ['$sort' => ['totalAge' => 1]]//排序
        ]);
        de($res);
    }
    //mongo数据模型数据的修改
    public function updateData(){
        $collection=$this->mongoConnect();
        //update永远只对查找的一条记录进行修改
        //增加年龄只修改一条记录，查找到的第一条记录进行修改。
       // $res=$collection->update(['Last_name'=>'wu'],['$inc'=>['Age'=>2]]);
        //$res=$collection->update(['Last_name'=>'wu'],['$set'=>['Age'=>2]]);
        //新增字段并且赋值
       // $res=$collection->update(['Last_name'=>'wu'],['$inc'=>['HobbyCount'=>2]]);
        //赋值并且增加字段
       // $res=$collection->update(['Last_name'=>'wu'],['$set'=>['Hobby'=>'basket']]);
        //删除字段
       //$res=$collection->update(['Last_name'=>'wu'],['$unset'=>['Hobby'=>'']]);
        //字段重命名
        //$res=$collection->update(['Last_name'=>'wu'],['$rename'=>['Age'=>'age']]);
        //$setOnInsert：设置了upsert为true，并且发生了插入操作的时候，将某个字段设置为特定的
       // $res = $collection->update(['Last_name' => 'wu'], ['$setOnInsert' => ['lang' => 'English']], ['upsert' => true]);
        //$push数组里面添加值
        //$res=$collection->update(['Last_name'=>'wu'],['$push'=>['E-Mail'=>'888887@qq.com']]);
        //向指定的添加多个字段mongo3.4以上取消了pushAll
        //$res=$collection->update(['Last_name'=>'wu'],['$pushAll'=>['E-Mail'=>['222222@qq.com','333333@qq.com']]]);
        //不用pushAll一次性提交多个值
       // $res=$collection->update(['Last_name'=>'wu'],['$push'=>['E-Mail'=>['$each'=>['789456123@qq.com','123456@qq.com']]]]);
        //$addToSet：将数据添加到数组中（只在目标数组没有该数据的时候才将数据添加到数组中）,用法和push一致。只是不添加已存在的数据
        //$res = $collection->update(['First Name' => 'Jet'], ['$addToSet' => ['E-Mail' => '123123@qq.com']]);
        //$res = $collection->update(['First Name' => 'Jet'], ['$addToSet' => ['E-Mail' => ['$each' => ['123123@qq.com', '666@qq.com']]]]);
        //对元素数组的删除,按位置删除pop,
       // $res=$collection->update(['Last_name'=>'wu'],['$pop'=>['E-Mail'=>1]]);
        //删除所有指定元素
        //$res=$collection->update(['Last_name'=>'wu'],['$pull'=>['E-Mail'=>'123456@qq.com']]);
        //$res=$collection->update(['Last_name'=>'wu'],['$pullAll'=>['E-Mail'=>['123456@qq.com','666666@qq.com']]]);
        //没找到数据进行插入
        //$res = $collection->findAndModify(['First Name' => 'Jet'], ['$push' => ['E-Mail' => '111@qq.com']]);
        //删多条
        $res = $collection->remove(['Age' => 26]);
        dd($res);
    }



    //链接Mongo配置
    public function mongoConnect(){
        $mongo=new \MongoClient('mongodb://localhost:27017');
        $db=$mongo->mf;
        $collection=$db->friend;
        return $collection;
    }
    /**************************上面是7.0以下操作，下面是php7.0以上mongo操作*******************************/
    public function getMongoDb(){
        $mongodb=new Mongodb(['dbname'=>'mf','collection'=>'friend']);
        return $mongodb;
    }
    //查询数据
    public function getDataList(){
        $mongodb=$this->getMongoDb();
        $dataList=$mongodb->query();
        dd($dataList);
    }
    //获取数据查询的数量
    public function getCount(){
        $mongodb=$this->getMongoDb();
        $dataList=$mongodb->getCount(['Age'=>31]);
        dd($dataList);
    }
    //通过mongodb进行分页
    public function getPageList(){
        $mongodb=$this->getMongoDb();
        //没数据会报错
        $dataList=$mongodb->page(['Age'=>30],1,5);
        dd($dataList);
    }
    //进行mongodb的修改
    public function updateDb(){
        $mongodb=$this->getMongoDb();
        //解决5.6 updateae只修改一条的问题。
        $res=$mongodb->update(['Last_name'=>'wu'],['Age'=>30]);
        dd($res);
    }
    //增加mongo记录
    public function insertDb(){
        $mongodb=$this->getMongoDb();
        //插入数据
        $doc=[
            'First_name'=>'jet',
            'Last_name'=>'wu',
            'Age'=>31,
            'Phone'=>'111',
            'Phone'=>'111',
            'lang'=>'china',
            'Address'=>[
                'Country'=>'China',
                'City'=>'Shen Zhen'
            ],
            'E-Mail'=>[
                '123456@qq.com',
                '666666@qq.com',
                '777777@qq.com'
            ]
        ];
        $res=$mongodb->insert($doc);
        dd($res);
    }
    //删除
    public function deleteDb(){
        $mongodb=$this->getMongoDb();
        $res=$mongodb->delete(['Age'=>31],1);
        dd($res);
    }
    public function getIncId(){
        $id=$this->generate_auto_increment_id('friend');
        dd($id);
    }

    //自增Id

    public function generate_auto_increment_id($namespace, array $option = array())
    {
        $option += array(
            'init' => 1,
            'step' => 1,
        );

        $instance = new \MongoDB();

        $instance = $instance->selectCollection('_seq', 'seq');

        $seq = $instance->db->command(array(
            'findAndModify' => 'seq',
            'query'         => array('_id' => $namespace),
            'update'        => array('$inc' => array('id' => $option['step'])),
            'new'           => true,
        ));

        if (isset($seq['value']['id'])) {
            return $seq['value']['id'];
        }

        $instance->insert(array(
            '_id' => $namespace,
            'id'  => $option['init'],
        ));

        return $option['init'];
    }




}
